# -.- coding: utf-8 -.-

from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from forms import SendingForm
from models import user, package
from django.template import RequestContext
import urllib, urllib2
import tweepy
import settings
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout
from django.core.files.storage import default_storage

# La vista download maneja la descarga de paquetes. Necesita tres parámetros, "request" es la petición para cargar la vista,
#"extra_context" es un hashmap en el que, en este caso, almecenamos la información del paquete que extraemos de la base de datos.

@login_required # Con @login_required obligamos a django a comprobar si el usuario está logueado en el sistema, si no lo está no puede acceder a la vista.
def download (request, id_package, extra_context={}):
	mini_user=user.objects.get(user=request.user)     # guardamos en mini_user el nick del usuario que realiza la petición.
	try:
		extra_context["paquete"] = package.objects.get(id=id_package,id_receiver=mini_user)  # al elemento "paquete" del hashmap se le asocia su id y la de su receptor.
		return render_to_response('error.html', extra_context, context_instance=RequestContext(request))  # si no encuentra el paquete muestra una url de error

	return render_to_response('download.html', extra_context, context_instance=RequestContext(request)) # si existe el paquete, y estás autorizado, lo descarga.

# La vista reject funciona de manera similar a la download, pero en lugar de descargar el paquete lo elimina del servidor.

@login_required
def reject (request, id_package, extra_context={}):
	mini_user=user.objects.get(user=request.user)
	try:
		paquete = package.objects.get(id=id_package,id_receiver=mini_user)
		paquete.delete()    # así eliminamos el paquete de la base de datos y del servidor.
	except package.DoesNotExist:
		return render_to_response('error.html', extra_context, context_instance=RequestContext(request))

	return HttpResponseRedirect(reverse(viewname='receive'))	# con esta sentencia podemos volver a la url asociada a la vista receive, que es la previa en la navegación.

# La vista receive se encarga de guardar los paquetes recibidos en un hashmap  ordenados por fecha de recepción
#que usaremos en el html receive para listar los paquetes con sus enlaces de forma simple y limpia.

@login_required
def receive(request, extra_context={}):
	mini_user = user.objects.get(user=request.user)
	extra_context['recibidos'] = mini_user.recibido.order_by('-date')
	return render_to_response('receive.html', extra_context, context_instance=RequestContext(request))

# La vista logout_twitter es la encargada de sacar al usuario del sistema y lo reenvía a la página de inicio.

@login_required
def logout_twitter(request, extra_context={}):
	logout(request)
	return HttpResponseRedirect(reverse(viewname='index'))	

# La vista thanks4send simplemente te dirije a la url de agradecimiento por enviar.

@login_required
def thanks4send(request, extra_context={}):
	return render_to_response('thanks4send.html', extra_context, context_instance=RequestContext(request))

# La vista howto te dirije al tutorial de la aplicación.

def howto(request, extra_context={}):
	return render_to_response('howto.html', extra_context, context_instance=RequestContext(request))

# La vista send tiene dos tareas, la primera es crear el formulario de envío tal y como se ve en el caso "else" y mostrar la página. Después, una vez rellenado el 
#formulario, al pulsar el botón de enviar se manda un POST con la información; si el formulario es válido pasa a la fase de autenticación en Twitter y el envío del
#paquete junto al aviso en Twitter.

@login_required
def send(request, extra_context={}):
	if request.method == 'POST':
		form = SendingForm(request.POST, request.FILES)  # SendingForm es una estructura de formulario facilitada por Django.
		if form.is_valid():  # Si la estructura que espera el SendingForm es válida se cumple la condición.
			usuario_logeado = request.user   # Obtenemos el usuario que está logeado.
			mini_user_logeado = user.objects.get(user=usuario_logeado)  # Sacamos la estructura de datos "user" de nuestra base de datos a través de su 
																		#campo "user" (nombre de usuario). Sentimos la ambigüedad en los nombres...

			# Tweepy es una API para Django que facilita el uso de la API de Twitter. Nuestro KEY y SECRET están almacenados en el "settings.py".

			auth = tweepy.OAuthHandler(settings.TWITTER_KEY, settings.TWITTER_SECRET) 	# De esta forma autorizamos nuestra aplicación y guardamos las 
																						#credenciales en una variable "auth".

			auth.set_access_token(mini_user_logeado.access_token,mini_user_logeado.access_secret)	# Extraemos de base de datos en token y secret del usuario
																									#y actualizamos las credenciales.

			api = tweepy.API(auth)	# Creamos un objeto api para manejar cómodamente la API.
			destinatario_twitter = api.get_user(request.POST.get('receiver_name'))	# Con la info del campo correspondiente del formulario obtenemos el usuario
																					#completo de Twitter asociado.
			id = form.save(destinatario_twitter, mini_user_logeado)	# Archivamos el paquete y guardamos la info asociada en base de datos. Id es el identificador
																	#de paquete asociado (un número).

			#Enviamos el aviso de twitter desde la cuenta del emisor a la cuenta del receptor
			url_paq = 'http://miniupload.alwaysdata.net/download/' + str(id)
			msg = '@'+ str(destinatario_twitter.screen_name) + ', te he dejado un archivo en #Miniupload. Descárgalo en: '+ url_paq
			api.update_status(msg) # Función de Tweepy para hacer una publicación en Twitter.

			return HttpResponseRedirect(reverse(viewname='thanks4send'))
	else:
		form = SendingForm()
	extra_context['templateForm']=form
	return render_to_response('sendingForm.html', extra_context, context_instance=RequestContext(request))

# La vista index dirije a la url index.

def index(request, extra_context={}):
	return render_to_response('index.html', extra_context, context_instance=RequestContext(request))

# La vista error dirije a la url error.

def error(request, extra_context={}):
	return render_to_response('error.html', extra_context, context_instance=RequestContext(request))

# La vista login_twitter es la que gestiona el proceso de login con Twitter. El proceso es semejante al explicado en la vista send. Pero en este caso se actualiza
#la cookie.

def login_twitter(request):
	auth = tweepy.OAuthHandler(settings.TWITTER_KEY, settings.TWITTER_SECRET, settings.LOGIN_URL)
	try:
		redirect_url = auth.get_authorization_url()
	except tweepy.TweepError:
		print 'Error getting request token.'

	request.session['request_token'] = (auth.request_token.key, auth.request_token.secret)
	return HttpResponseRedirect(redirect_url)

# La vista confirm_twitter es la que se encarga de el proceso de que el usuario permita a nuestra aplicación usar sus datos para poder logearse con su cuenta
#de Twitter. Aquí creamos las entradas de la base de datos con los datos de los usuarios que quieren usar la aplicación y, además, creamos las entradas de la 
#base de datos de django (cuyos datos usaremos para la cookie de autenticación).

def confirm_twitter(request):
	verifier = request.GET.get('oauth_verifier')

	if verifier is None or verifier == "":
		return HttpResponseRedirect('/')
	
	auth = tweepy.OAuthHandler(settings.TWITTER_KEY, settings.TWITTER_SECRET)
	token = request.session['request_token']
	auth.set_request_token(token[0],token[1])

	try:
		auth.get_access_token(verifier)
	except:
		print "Error! Failed to get access token."

	api = tweepy.API(auth)

	#Guardamos la tupla en bbdd
	try:
		app_user = user.objects.get(username=auth.get_username())
		
		if app_user.access_token is None or app_user.access_token == "":
			app_user.access_token = auth.access_token.key
			app_user.access_secret = auth.access_token.secret
			app_user.user.set_password(auth.access_token.key)
			app_user.user.save()
			app_user.save()
	except user.DoesNotExist:
		django_user = User(
			username = auth.get_username(),
		)
		django_user.set_password(auth.access_token.key)
		django_user.save()

		app_user = user(
			user = django_user,
			username = auth.get_username(),
			id_twitter = api.me().id,
			access_token = auth.access_token.key,
			access_secret = auth.access_token.secret,
		)
		app_user.save()

	django_user = authenticate(
		username = app_user.username,
		password = auth.access_token.key
	)

	print django_user
	print django_user.username

	request.session['loggedin'] = "twitter"
	login(request, django_user)
	print request
	return HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)

